package com.xwb.laboratory.test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.LockSupport;

public class MyFutureTask<T> implements Runnable{

	private Callable<T> target;
	
	private T result;
	
	private String state;
	
	private BlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();
	
	public MyFutureTask(Callable<T> callable) {
		target = callable;
		state = "new";
	}

	@Override
	public void run() {
		try {
			state = "running";
			result = target.call();
			state = "done";
		} catch (Exception e) {
			state = "error";
			e.printStackTrace();
		} finally {
			if("done".equals(this.state)) {
				while(true) {
					Thread t = waiters.poll();
					if(t != null) {						
						LockSupport.unpark(t);
					}else {
						break;
					}
				}
			}
		}
	}
	
	T get() {
		if(!"done".equals(this.state)) {
			waiters.offer(Thread.currentThread());
		}
		while(!"done".equals(this.state)) {
			LockSupport.park();
		}
		return this.result;
	}
}
